iT邦幫忙

2021 iThome 鐵人賽

DAY 19
0
自我挑戰組

React 學習之路系列 第 19

打造你自己的 Hook ( Day19 )

  • 分享至 

  • xImage
  •  

Hook 概觀 的文章中,曾經寫過一個打造 Hook 的例子。複習一下,發現應該要修改命名為 useTimeout 來符合自動 Hook 判別。

// myTimeout => useTimeout
function useTimeout(delay) {
  const [show, setShow] = React.useState(false);

  React.useEffect(
    () => {
      let timer1 = setTimeout(() => setShow(true), delay * 1000);
      return () => {
        clearTimeout(timer1);
      };
    },
    []
  );

  return show;
}

function Vender() {
  const [banana, takeBanana] = React.useState(0);
  const timer1 = useTimeout(1)
  const timer2 = useTimeout(3)

  return (
    //略
  );
}

使用一個自定義的 Hook ,文件有提供一些思索的點如羅列

以下問答以之前的 useTimeout 例子為例。

請問我必須以「use」開頭命名我自定義的 Hook 嗎?

一個自定義的 Hook 不需要一個特定的宣告。我們可以決定它需要接受什麼參數,以及它應該回傳什麼(如果有的話)。換句話說,它像一個普通的 function。它的命名開頭應該總是為 use,所以你可以一眼就看出 Hook 的規則適用於它。

請問兩個 component 使用相同的 Hook 是共享 state 的嗎?
從 timer 裡面的例子就可以看到,它 delay 的時間不一樣,之間並沒有相互影響。

自定義的 Hook 是如何隔離 state 的?
同等於呼叫 useState 和 useEffect 多次,彼此建立起時都是獨立的。

在 Hook 之間傳遞資訊

官網的例子,使用 Selector 去選擇訂閱哪一個 id ,並用 setRecipientID 去更新 recipient 的最新狀態。

const friendList = [
  { id: 1, name: 'Phoebe' },
  { id: 2, name: 'Rachel' },
  { id: 3, name: 'Ross' },
];

function ChatRecipientPicker() {
  const [recipientID, setRecipientID] = useState(1);
  const isRecipientOnline = useFriendStatus(recipientID);

  return (
    <>
      <Circle color={isRecipientOnline ? 'green' : 'red'} />
      <select
        value={recipientID}
        onChange={e => setRecipientID(Number(e.target.value))}
      >
        {friendList.map(friend => (
          <option key={friend.id} value={friend.id}>
            {friend.name}
          </option>
        ))}
      </select>
    </>
  );
}

reducer Hook 與其他

在打造你自己的 Hook 裡有提到一些對於新學習 React 的人可能不熟悉的東西,例如共享 stateful 邏輯會用到的
render props、higher-order component,或是 useState 的替代方案 reducer Hook,以及更複雜 component 會使用的 state 容器 Redux。將在之後的學習中補充。

以上今天。

參考資料:
https://zh-hant.reactjs.org/docs/hooks-custom.html


上一篇
Hook 的規則 ( Day18 )
下一篇
Render Props ( Day20 )
系列文
React 學習之路30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言